"""日志工具（分级日志+审计日志）"""
"""日志工具（原结构保留，补充审计日志字段）"""
import os
import logging
import logging.handlers
import json
from datetime import datetime
from typing import Dict, Any, Optional
from .constants import LOG_LEVELS


class JSONFormatter(logging.Formatter):
    """JSON格式的日志格式化器"""
    def format(self, record: logging.LogRecord) -> str:
        """格式化日志记录为JSON字符串"""
        log_data = {
            'timestamp': datetime.fromtimestamp(record.created).isoformat(),
            'level': record.levelname,
            'name': record.name,
            'message': record.getMessage(),
            'module': record.module,
            'line': record.lineno,
        }
        
        # 添加异常信息
        if record.exc_info:
            log_data['exception'] = self.formatException(record.exc_info)
        
        # 添加额外的上下文信息
        if hasattr(record, 'extra'):
            log_data.update(record.extra)
        
        # 添加审计日志字段
        if hasattr(record, 'audit'):
            log_data['audit'] = record.audit
            log_data['audit_user'] = getattr(record, 'audit_user', 'system')
            log_data['audit_action'] = getattr(record, 'audit_action', 'unknown')
            log_data['audit_resource'] = getattr(record, 'audit_resource', 'unknown')
            log_data['audit_status'] = getattr(record, 'audit_status', 'success')
        
        return json.dumps(log_data, ensure_ascii=False)


class Logger:
    """日志管理器"""
    _loggers: Dict[str, logging.Logger] = {}
    _audit_logger: Optional[logging.Logger] = None
    
    @classmethod
    def get_logger(cls, name: str = 'fin_senti_platform', log_level: str = 'INFO') -> logging.Logger:
        """
        获取或创建日志记录器
        Args:
            name: 日志记录器名称
            log_level: 日志级别
        Returns:
            日志记录器实例
        """
        if name not in cls._loggers:
            logger = logging.getLogger(name)
            logger.setLevel(LOG_LEVELS.get(log_level.upper(), logging.INFO))
            
            # 防止重复添加处理器
            if not logger.handlers:
                # 控制台处理器
                console_handler = logging.StreamHandler()
                console_handler.setFormatter(JSONFormatter())
                logger.addHandler(console_handler)
                
                # 文件处理器
                log_dir = os.path.join(os.getcwd(), 'logs')
                os.makedirs(log_dir, exist_ok=True)
                log_file = os.path.join(log_dir, f'{name}.log')
                
                file_handler = logging.handlers.RotatingFileHandler(
                    log_file,
                    maxBytes=10*1024*1024,  # 10MB
                    backupCount=5,
                    encoding='utf-8'
                )
                file_handler.setFormatter(JSONFormatter())
                logger.addHandler(file_handler)
            
            cls._loggers[name] = logger
        
        return cls._loggers[name]
    
    @classmethod
    def get_audit_logger(cls) -> logging.Logger:
        """
        获取审计日志记录器
        Returns:
            审计日志记录器实例
        """
        if cls._audit_logger is None:
            cls._audit_logger = cls.get_logger('audit')
            
            # 为审计日志添加单独的文件处理器
            log_dir = os.path.join(os.getcwd(), 'logs')
            os.makedirs(log_dir, exist_ok=True)
            audit_log_file = os.path.join(log_dir, 'audit.log')
            
            audit_file_handler = logging.handlers.RotatingFileHandler(
                audit_log_file,
                maxBytes=10*1024*1024,  # 10MB
                backupCount=30,  # 保留30天的审计日志
                encoding='utf-8'
            )
            audit_file_handler.setFormatter(JSONFormatter())
            
            # 确保审计日志处理器只处理审计日志
            for handler in cls._audit_logger.handlers[:]:
                if isinstance(handler, logging.handlers.RotatingFileHandler) and \
                   handler.baseFilename != audit_log_file:
                    cls._audit_logger.removeHandler(handler)
            
            cls._audit_logger.addHandler(audit_file_handler)
        
        return cls._audit_logger
    
    @classmethod
    def log_audit(cls, user: str, action: str, resource: str, status: str = 'success', 
                 details: Optional[Dict[str, Any]] = None) -> None:
        """
        记录审计日志
        Args:
            user: 用户标识
            action: 操作类型
            resource: 操作资源
            status: 操作状态（success/failed）
            details: 操作详情
        """
        audit_logger = cls.get_audit_logger()
        
        # 创建审计日志记录
        extra = {
            'audit': True,
            'audit_user': user,
            'audit_action': action,
            'audit_resource': resource,
            'audit_status': status
        }
        
        # 添加详情
        if details:
            extra['audit_details'] = details
        
        # 记录审计日志
        if status == 'success':
            audit_logger.info(f"审计: {user} {action} {resource} 成功", extra=extra)
        else:
            audit_logger.warning(f"审计: {user} {action} {resource} 失败", extra=extra)


# 创建全局日志记录器实例
def get_logger(name: str = 'fin_senti_platform', log_level: str = 'INFO') -> logging.Logger:
    """获取日志记录器的便捷函数"""
    return Logger.get_logger(name, log_level)

def get_audit_logger() -> logging.Logger:
    """获取审计日志记录器的便捷函数"""
    return Logger.get_audit_logger()

def log_audit(user: str, action: str, resource: str, status: str = 'success', 
              details: Optional[Dict[str, Any]] = None) -> None:
    """记录审计日志的便捷函数"""
    Logger.log_audit(user, action, resource, status, details)


# 初始化根日志配置
root_logger = logging.getLogger()
root_logger.setLevel(logging.INFO)

# 移除默认处理器
for handler in root_logger.handlers[:]:
    root_logger.removeHandler(handler)

# 添加控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(JSONFormatter())
root_logger.addHandler(console_handler)